﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Hive.Core;

namespace Hive.Bot.Tasks
{
    public class MoveTask : ITask
    {
        protected Location destination;
        protected Ant ant;
        protected MoveTask(Location destination)
        {
            this.destination = destination;
        }

        public virtual IEnumerable<int> CalculateEfficiencies(IEnumerable<Ant> ants)
        {
            return ants.Select(a => GetEfficiencyByDistance(Env.Map.GetDistance(a.Location, destination)));
        }

        public static int GetEfficiencyByDistance(int distance)
        {
            if (distance == 0)
                return 0;

            var max = Env.Map.Height + Env.Map.Width;
            if (distance > max)
                distance = max;
            return (int)Math.Round(100.0 * (max - distance) / max);
        }

        public virtual void Assign(Ant ant)
        {
            this.ant = ant;
        }

        public virtual Order Execute()
        {
            var route = Env.Map.BuildPath(ant.Location, destination);
            //var route = Env.Map.DirectionTo(ant.Location, l => l == destination);
            return GetOrderByRoute(route);
        }

        protected Order GetOrderByRoute(List<Location> route)
        {
            if (route.Any())
            {
                return new Order()
                {
                    Destination = route.First(),
                    Ant = ant,
                    Efficiency = 0//CalculateEfficiency(ant)
                };
            }
            else
            {
                if (ant.Location == destination)
                {
                    return new Order()
                    {
                        Destination = ant.Location,
                        Ant = ant,
                        Efficiency = 0//CalculateEfficiency(ant)
                    };
                }
            }

            throw new ApplicationException(string.Format("Cannot move ant id {0} at {1} to {2}", ant.Id, ant.Location, destination));
        }

        public virtual bool IsAssigned
        {
            get { return ant != null && destination != null; }
        }

        public override string ToString()
        {
            return string.Format("destination = {0}", destination);
        }
    }
}
